import { Controller, Get, Patch, Body, UseGuards, Param, ParseIntPipe } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiParam, ApiBody } from '@nestjs/swagger';
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
import { CurrentUser } from '../../auth/decorators/current-user.decorator';
import { User } from '../entities/user.entity';
import { UsersService } from '../services/users.service';
import { UpdateUserDto } from '../dto/update-user.dto';
import { ApiResponseDto } from '../../common/dto/api-response.dto';
import { AppI18nService } from '../../i18n/i18n.service';
import { CurrentLanguage } from '../../i18n/language.decorator';

@ApiTags('users')
@ApiBearerAuth('JWT-auth')
@Controller('users')
@UseGuards(JwtAuthGuard)
export class UsersController {
    constructor(
        private readonly usersService: UsersService,
        private readonly appI18nService: AppI18nService
    ) { }

    @Get('me')
    @ApiOperation({
        summary: 'Get current user information',
        description: 'Retrieves the profile information of the currently authenticated user'
    })
    @ApiResponse({
        status: 200,
        description: 'Current user information retrieved successfully',
        type: ApiResponseDto<User>
    })
    @ApiResponse({
        status: 401,
        description: 'Unauthorized - Invalid or missing JWT token'
    })
    getCurrentUser(@CurrentUser() user: User, @CurrentLanguage() language: string): ApiResponseDto<User> {
        const message = this.appI18nService.getUserMessage('current_user_retrieved', {}, language);
        return ApiResponseDto.success(user, message);
    }

    @Patch('me')
    @ApiOperation({
        summary: 'Update current user information',
        description: 'Updates the profile information of the currently authenticated user'
    })
    @ApiBody({
        type: UpdateUserDto,
        description: 'User information to update'
    })
    @ApiResponse({
        status: 200,
        description: 'User information updated successfully',
        type: ApiResponseDto<User>
    })
    @ApiResponse({
        status: 400,
        description: 'Bad request - Invalid update data'
    })
    @ApiResponse({
        status: 401,
        description: 'Unauthorized - Invalid or missing JWT token'
    })
    async updateCurrentUser(
        @CurrentUser() user: User,
        @Body() updateUserDto: UpdateUserDto,
        @CurrentLanguage() language: string
    ): Promise<ApiResponseDto<User>> {
        const updatedUser = await this.usersService.updateUser(user.id, updateUserDto, language);
        const message = this.appI18nService.getUserMessage('updated', {}, language);
        return ApiResponseDto.success(updatedUser, message);
    }

    @Get(':id')
    @ApiOperation({
        summary: 'Get user by ID',
        description: 'Retrieves user information by user ID (Admin function)'
    })
    @ApiParam({
        name: 'id',
        description: 'User ID',
        type: 'number',
        example: 1
    })
    @ApiResponse({
        status: 200,
        description: 'User information retrieved successfully',
        type: ApiResponseDto<User>
    })
    @ApiResponse({
        status: 401,
        description: 'Unauthorized - Invalid or missing JWT token'
    })
    @ApiResponse({
        status: 404,
        description: 'User not found'
    })
    async getUserById(
        @Param('id', ParseIntPipe) id: number,
        @CurrentLanguage() language: string
    ): Promise<ApiResponseDto<User>> {
        const user = await this.usersService.findById(id, language);
        const message = this.appI18nService.getUserMessage('retrieved', {}, language);
        return ApiResponseDto.success(user, message);
    }

    @Get('wallet/:address')
    @ApiOperation({
        summary: 'Get user by wallet address',
        description: 'Retrieves user information by Ethereum wallet address'
    })
    @ApiParam({
        name: 'address',
        description: 'Ethereum wallet address',
        type: 'string',
        example: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6'
    })
    @ApiResponse({
        status: 200,
        description: 'User information retrieved successfully',
        type: ApiResponseDto<User>
    })
    @ApiResponse({
        status: 401,
        description: 'Unauthorized - Invalid or missing JWT token'
    })
    @ApiResponse({
        status: 404,
        description: 'User not found'
    })
    async getUserByWallet(
        @Param('address') address: string,
        @CurrentLanguage() language: string
    ): Promise<ApiResponseDto<User>> {
        const user = await this.usersService.findByWallet(address, language);
        const message = this.appI18nService.getUserMessage('retrieved', {}, language);
        return ApiResponseDto.success(user, message);
    }
}
